#include <iostream>
#include <string>
#include <memory>


// // 1. 简单工厂模式

// // 抽象产品：形状
// class Shape
// {
// public:
//     virtual void Draw() = 0; // 公共接口
//     // 基类析构函数设为虚函数后，子类析构函数会自动参与多态，
//     // 确保通过基类指针销毁子类对象时，析构函数的调用符合 “实际对象类型”。
//     virtual ~Shape() = default;
// };

// // 具体产品1：圆形
// class Circle : public Shape
// {
// public:
//     void Draw() override
//     {
//         std::cout << "draw circle" << std::endl;
//     }
// };

// // 具体产品2：矩阵
// class Rectangle : public Shape
// {
// public:
//     void Draw() override
//     {
//         std::cout << "draw rectangle" << std::endl;
//     }
// };

// // 具体工厂
// class ShapeFactory 
// {
// public:
//     static std::unique_ptr<Shape> CreateShape(const std::string& type)
//     {
//         if(type == "circle")
//             return std::make_unique<Circle>();
//         else if(type == "rectangle")
//             return std::make_unique<Rectangle>();
//         else
//             return nullptr;
//     }
// };

// int main()
// {
//     std::unique_ptr<Shape> circle = ShapeFactory::CreateShape("circle");
//     std::unique_ptr<Shape> rect = ShapeFactory::CreateShape("rectangle");

//     if (circle) circle->Draw();
//     if (rect) rect->Draw();

//     return 0;
// }


// // 2. 工厂方法模式

// // 抽象产品：形状
// class Shape
// {
// public:
//     virtual void Draw() = 0; // 公共接口
//     // 基类析构函数设为虚函数后，子类析构函数会自动参与多态，
//     // 确保通过基类指针销毁子类对象时，析构函数的调用符合 “实际对象类型”。
//     virtual ~Shape() = default;
// };

// // 具体产品1：圆形
// class Circle : public Shape
// {
// public:
//     void Draw() override
//     {
//         std::cout << "draw circle" << std::endl;
//     }
// };

// // 具体产品2：矩阵
// class Rectangle : public Shape
// {
// public:
//     void Draw() override
//     {
//         std::cout << "draw rectangle" << std::endl;
//     }
// };

// // 抽象工厂
// class ShapeFactory
// {
// public:
//     virtual std::unique_ptr<Shape> CreateShape() = 0;
//     virtual ~ShapeFactory() = default;
// };

// // 具体工厂1：创建圆形
// class CircleFactory : public ShapeFactory 
// {
// public:
//     std::unique_ptr<Shape> CreateShape() override
//     {
//         return std::make_unique<Circle>();
//     }
// };

// // 具体工厂2：创建矩形
// class RectangleFactory : public ShapeFactory 
// {
// public:
//     std::unique_ptr<Shape> CreateShape() override
//     {
//         return std::make_unique<Rectangle>();
//     }
// };

// int main()
// {
//     // 工厂本身也用智能指针，彻底避免手动释放
//     std::unique_ptr<ShapeFactory> circle_factory = std::make_unique<CircleFactory>();
//     std::unique_ptr<ShapeFactory> rect_factory = std::make_unique<RectangleFactory>();

//     std::unique_ptr<Shape> circle = circle_factory->CreateShape();
//     std::unique_ptr<Shape> rect = rect_factory->CreateShape();

//     circle->Draw();
//     rect->Draw();

//     return 0;
// }


// 3. 抽象方法

// 抽象产品族：手机和平板
class Phone
{
public:
    virtual void Call() = 0;
    virtual ~Phone() = default;
};
class Tablet
{
public:
    virtual void Watch() = 0;
    virtual ~Tablet() = default;
};

// 具体产品族1：华为系列
class HuaweiPhone : public Phone
{
public:
    void Call() override
    {
        std::cout << "Huawei Call" << std::endl;
    }
};
class HuaweiTablet : public Tablet
{
public:
    void Watch() override
    {
        std::cout << "Huawei videos" << std::endl;
    }
};

// 具体产品族2：苹果系列
class IPhone : public Phone
{
public:
    void Call() override
    {
        std::cout << "IPhone Call" << std::endl;
    }
};
class Ipad : public Tablet
{
public:
    void Watch() override
    {
        std::cout << "Ipad videos" << std::endl;
    }
};

// 抽象工厂：创建整个产品族的接口
class AbstractFactory
{
public:
    virtual std::unique_ptr<Phone> CreatePhone() = 0;
    virtual std::unique_ptr<Tablet> CreateTablet() = 0;
    virtual ~AbstractFactory() = default;
};

// 具体工厂1：华为工厂
class HuaweiFactory : public AbstractFactory
{
public:
    std::unique_ptr<Phone> CreatePhone() override
    {
        return std::make_unique<HuaweiPhone>();
    }
    std::unique_ptr<Tablet> CreateTablet() override
    {
        return std::make_unique<HuaweiTablet>();
    }
};

// 具体工厂2：苹果工厂
class AppleFactory : public AbstractFactory
{
public:
    std::unique_ptr<Phone> CreatePhone() override
    {
        return std::make_unique<IPhone>();
    }
    std::unique_ptr<Tablet> CreateTablet() override
    {
        return std::make_unique<Ipad>();
    }
};

int main()
{
    std::unique_ptr<AbstractFactory> huawei_factory = std::make_unique<HuaweiFactory>();
    std::unique_ptr<AbstractFactory> apple_factory = std::make_unique<AppleFactory>();

    std::unique_ptr<Phone> huawei_phone = huawei_factory->CreatePhone();
    std::unique_ptr<Tablet> huawei_tablet = huawei_factory->CreateTablet();

    std::unique_ptr<Phone> iphone = apple_factory->CreatePhone();
    std::unique_ptr<Tablet> ipad = apple_factory->CreateTablet();

    huawei_phone->Call();
    huawei_tablet->Watch();

    iphone->Call();
    ipad->Watch();

    return 0;
}